package com.project.demo.util;

import com.alibaba.fastjson.JSONObject;
import com.project.demo.entity.SysKey;
import com.project.demo.parameter.MasterPrivateKey;
import com.project.demo.parameter.PairingParameter;
import com.project.demo.parameter.PublicKey;
import com.project.demo.parameter.SystemKey;
import it.unisa.dia.gas.jpbc.Pairing;
import it.unisa.dia.gas.plaf.jpbc.pairing.PairingFactory;
import org.springframework.util.StringUtils;
import sun.misc.BASE64Encoder;

import javax.swing.*;
import java.io.*;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;


public class SysKeyUtil {

    /**
     * public static SystemKey getSysKey(SysKey sysKey){
     * Pairing pairing = PairingFactory.getPairing("params/curves/a.properties");
     * PairingParameter pairingParameter = new PairingParameter();
     * pairingParameter.setPairing(pairing);
     * pairingParameter.setG0(pairing.getG1());
     * pairingParameter.setG1(pairing.getGT());
     * pairingParameter.setZr(pairing.getZr());
     * pairingParameter.setGenerator(pairing.getG1().newElementFromBytes(sysKey.getGenerator().getBytes()));
     * <p>
     * SystemKey systemKey = new SystemKey();
     * PublicKey publicKey = new PublicKey();
     * publicKey.setPairingParameter(pairingParameter);
     * publicKey.setH(pairing.getG1().newElementFromBytes(sysKey.getH().getBytes()));
     * publicKey.setEgg_a(pairing.getG1().newElementFromBytes(sysKey.getEggA().getBytes()));
     * publicKey.setF(pairing.getG1().newElementFromBytes(sysKey.getF().getBytes()));
     * <p>
     * systemKey.setPublicKey(publicKey);
     * <p>
     * MasterPrivateKey masterPrivateKey = new MasterPrivateKey(pairingParameter);
     * masterPrivateKey.setAlpha(pairing.getG1().newElementFromBytes(sysKey.getAlpha().getBytes()).getImmutable());
     * masterPrivateKey.setBeta(pairing.getG1().newElementFromBytes(sysKey.getBeta().getBytes()).getImmutable());
     * masterPrivateKey.setG_alpha(pairing.getG1().newElementFromBytes(sysKey.getGAlpha().getBytes()).getImmutable());
     * <p>
     * systemKey.setMasterPrivateKey(masterPrivateKey);
     * System.out.println(systemKey);
     * return systemKey;
     * <p>
     * }
     */
    private static String pairingParametersFileName = System.getProperty("user.dir") + "\\src\\main\\resources\\"+"security_params/security_level_" + 128 + "bits.properties";
    private static String pkFileName = System.getProperty("user.dir") + "\\src\\main\\resources\\demo\\publicKey";
    private static String mskFileName = System.getProperty("user.dir") + "\\src\\main\\resources\\demo\\masterPrivateKey";
    private static String publicKey;
    private static String masterPrivateKey;
    private static String plainFileName;
    private static String data;
    private static String policyFileName = System.getProperty("user.dir") + "\\src\\main\\resources\\demo\\config.json";;
    private static String lastPath = "~/";

    public static String getPublicKey() {
        return publicKey;
    }

    /**
     * 生成系统公钥\主密钥
     */
    public static void getSysKey() {
        if (publicKey == null && masterPrivateKey == null) {
            Properties pkProp = loadPropFromFile(pkFileName);
            Properties mskProp = loadPropFromFile(mskFileName);
            if (pkProp.size() <= 0) {
                Map<String, Properties> setup = CPABE.setup(pairingParametersFileName, pkFileName, mskFileName);
                pkProp = setup.get("pkProp");
                mskProp = setup.get("mskProp");
            }
            JSONObject jsonObject = new JSONObject();
            // 将 Properties 对象中的键值对添加到 Map 中
            for (String key : pkProp.stringPropertyNames()) {
                jsonObject.put(key, pkProp.getProperty(key));
                publicKey = jsonObject.toJSONString();
            }

            for (String key : mskProp.stringPropertyNames()) {
                jsonObject.put(key, mskProp.getProperty(key));
                masterPrivateKey = jsonObject.toJSONString();
            }
        }
    }


    /**
     * 生成用户私钥
     */
    public static Properties getUserPrivateKey(String[] userAttList) {
        try {
            Properties keygen = CPABE.keygen(userAttList, pkFileName, mskFileName);
            return keygen;
        } catch (NoSuchAlgorithmException ex) {
            ex.printStackTrace();
        }
        return null;
    }

    /**
     * 加密文件
     */
    public static void kemEncrypt(String data,String fileName) {
        try {
            CPABE.kemEncrypt(data, policyFileName, pkFileName, fileName);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }


    /**
     * 解密文件
     */
    public static String kemDecrypt(String ctFileName,Properties skProp) {
        try {
            String res =CPABE.kemDecrypt(ctFileName, skProp);
            return res;
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return null;
    }

    public static Properties loadPropFromFile(String fileName) {
        Properties prop = new Properties();
        try (FileInputStream in = new FileInputStream(fileName)) {
            prop.load(in);
        } catch (IOException e) {
            System.out.println("not exit"+fileName);
        }
        return prop;
    }

    private static void validateAndCreateFile(File file) throws Exception{
        if (!file.getParentFile().exists()) {
            file.getParentFile().mkdirs();
        }
        file.createNewFile();
    }

}
